﻿
namespace HSS.ComponentModel
{
	#region Using Directives
	using System;
	using System.ComponentModel;
	using System.Globalization;
	#endregion

	#region DateTimeConverter
	/// <summary>
	/// Provides a type converter to convert DateTime objects to and from various other representations.
	/// </summary>
	public class DateTimeConverter : TypeConverter
	{
		/// <summary>
		/// Returns whether this converter can convert an object of the given type to the type of this converter.
		/// </summary>
		/// <param name="context">An ITypeDescriptorContext that provides a format context.</param>
		/// <param name="sourceType">A Type that represents the type you wish to convert from.</param>
		/// <returns>true if this object can perform the conversion; otherwise, false.</returns>
		public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
		{
			return ((sourceType == typeof(string)) || base.CanConvertFrom(context, sourceType));
		}
		/// <summary>
		/// Gets a value indicating whether this converter can convert an object to the given destination type using the context.
		/// </summary>
		/// <param name="context">An ITypeDescriptorContext that provides a format context.</param>
		/// <param name="destinationType">A Type that represents the type you wish to convert to.</param>
		/// <returns>true if this converter can perform the conversion; otherwise, false.</returns>
		public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
		{
			return ((destinationType == typeof(string)) || base.CanConvertTo(context, destinationType));
		}
		/// <summary>
		/// Converts the given value object to a DateTime.
		/// </summary>
		/// <param name="context">An ITypeDescriptorContext that provides a format context.</param>
		/// <param name="culture">An optional CultureInfo. If not supplied, the current culture is assumed.</param>
		/// <param name="value">The Object to convert.</param>
		/// <returns>An Object that represents the converted value.</returns>
		public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
		{
			var s = value as string;
			if (null != s)
			{
				s = s.Trim();
				if (s.Length == 0)
					return DateTime.MinValue;
				DateTimeFormatInfo provider = null;
				if (culture != null)
					provider = (DateTimeFormatInfo)culture.GetFormat(typeof(DateTimeFormatInfo));
				if (provider != null)
					return DateTime.Parse(s, provider);
				return DateTime.Parse(s, culture);
			}
			return base.ConvertFrom(context, culture, value);
		}
		/// <summary>
		/// Converts the given value object to a DateTime using the arguments.
		/// </summary>
		/// <param name="context">An ITypeDescriptorContext that provides a format context.</param>
		/// <param name="culture">An optional CultureInfo. If not supplied, the current culture is assumed.</param>
		/// <param name="value">The Object to convert.</param>
		/// <param name="destinationType">The Type to convert the value to.</param>
		/// <returns>An Object that represents the converted value.</returns>
		public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
		{
			if ((destinationType == typeof(string)) && (value is DateTime))
			{
				string shortDatePattern;
				DateTime time = (DateTime)value;
				if (time == DateTime.MinValue)
					return string.Empty;
				if (culture == null)
					culture = CultureInfo.CurrentCulture;
				DateTimeFormatInfo format = null;
				format = (DateTimeFormatInfo)culture.GetFormat(typeof(DateTimeFormatInfo));
				if (culture == CultureInfo.InvariantCulture)
				{
					if (time.TimeOfDay.TotalSeconds == 0.0)
						return time.ToString("yyyy-MM-dd", culture);
					return time.ToString(culture);
				}
				if (time.TimeOfDay.TotalSeconds == 0.0)
					shortDatePattern = format.ShortDatePattern;
				else
					shortDatePattern = format.ShortDatePattern + " " + format.ShortTimePattern;
				return time.ToString(shortDatePattern, CultureInfo.CurrentCulture);
			}
			return base.ConvertTo(context, culture, value, destinationType);
		}
	}
	#endregion
}